home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / pcmagazi / 1989 / 20 / debugscr.asm < prev    next >
Assembly Source File  |  1989-10-13  |  17KB  |  373 lines

  1. ; DebugScr converts any disk file into a hexadecimal ASCII script text file.
  2. ; Unlike binary files like .EXEs, .COMs or 123 data files, the script file can
  3. ; then be sent via a data service like MCI or CIS as an ordinary text file.
  4. ; The recipient recreates the original binary file by redirecting the script
  5. ; file as Debug's input thus:
  6. ;
  7. ;              DEBUG < filename.SCR
  8. ;
  9. ; where filename.SCR is the name of script file created by DEBUGSCR.COM.
  10.  
  11. _TEXT          SEGMENT PUBLIC 'CODE'
  12.                ASSUME  CS:_TEXT,DS:_TEXT,ES:_TEXT,SS:_TEXT
  13.                ORG     100H
  14. START:         JMP     MAIN
  15.  
  16. ;              DATA AREA
  17. ;              ---------
  18. SIGNATURE      DB      CR,SPACE,SPACE,SPACE,CR,LF
  19. COPYRIGHT      DB      "DEBUGSCR 1.0 (C) 1989 Ziff Communications Co. ",CR,LF
  20. PROGRAMMER     DB      "PC Magazine ",BOX," Michael J. Mefford",CR,LF,LF
  21.  
  22. DB             "Syntax:  DEBUGSCR filespec [/N]",CR,LF,LF
  23. DB             "/N = No instruction messages in script",CR,LF,LF
  24. DB             "filename.SCR will be created",CR,LF
  25. DB             "To recreate file, Enter",CR,LF,LF
  26.  
  27. DB             TAB,     "DEBUG < filename.SCR",CR,LF,LF,"$",CTRL_Z
  28.  
  29. TAB            EQU     9
  30. CR             EQU     13
  31. LF             EQU     10
  32. CTRL_Z         EQU     26
  33. SPACE          EQU     32
  34. BOX            EQU     254
  35.  
  36. FILESPEC_START DW     ?
  37. FILESPEC_END   DW     ?
  38. FILENAME_START DW     ?
  39. FILENAME_LEN   DW     ?
  40. DOT_ADDRESS    DW     ?
  41.  
  42. EXE_FLAG       DB     0                        ;Set if and EXE 
  43.                                                ; extension found.
  44. MSG_FLAG       DB     0                        ;Set if no suppress script msg.
  45. FILE_LENGTH    DW     ?
  46. HANDLE         DW     ?
  47. LINE_NO        DW     100H
  48. CHAR_CT        DW     ?
  49.  
  50. FILE           DB     "File"
  51. NOT_FOUND      DB     " not found",CR,LF,LF,"$"
  52. DISK_ERROR     DB     "Disk error",CR,LF,LF,"$"
  53. DOT_SCR        DB     ".SCR",0,"$"
  54. EXE            DB     ".EXE",CR,LF
  55. TOO_BIG        DB     "Input file too big; can't be more than 60K",CR,LF,LF,"$"
  56. NOT_ENOUGH     DB     "Not enough memory; requires 64K",CR,LF,LF,"$"
  57. CREATED        DB     "created",CR,LF,LF,"$"
  58.  
  59. RCX            DB     " RCX",CR,LF
  60. WQ             DB     " W",CR,LF
  61.                DB     " Q",CR,LF,CR,LF
  62.  
  63. SCRIPT_END DB  TAB, "If you have downloaded this script file, remove",CR,LF
  64.            DB  TAB, "any captured communications header and then enter",CR,LF
  65.            DB  CR,LF,TAB,TAB,"DEBUG < filename",CR,LF,CR,LF
  66.            DB  TAB,"where filename is the name of this script file.",CR,LF
  67. SCRIPT_END_LEN EQU $ - SCRIPT_END
  68.  
  69. EXE_MSG   DB  CR,LF
  70.           DB  TAB,"Note this is an EXE script.  Debug will not create",CR,LF
  71.           DB  TAB,"a file with an EXE name extension.  You have to add",CR,LF
  72.           DB  TAB,"the EXE extension yourself AFTER the file is created",CR,LF
  73.           DB  TAB,"by Debug by entering the following at the DOS prompt",CR,LF
  74.           DB  CR,LF
  75.  
  76.           DB  TAB,"RENAME "
  77. EXE_MSG_LENGTH EQU    $ - EXE_MSG
  78.  
  79. ;              CODE AREA
  80. ;              ---------
  81. MAIN           PROC   NEAR
  82.                CLD
  83.                MOV    DX,OFFSET SIGNATURE      ;Display copyright and syntax.
  84.                CALL   PRINT_STRING
  85.  
  86.                MOV    BX,64 / 16 * 1024        ;Minimum 64K memory required.
  87.                MOV    AH,4AH
  88.                INT    21H
  89.                MOV    DX,OFFSET NOT_ENOUGH
  90.                JNC    CAPITALIZE
  91.                JMP    ERROR_EXIT
  92.  
  93. CAPITALIZE:    MOV    SI,81H                   ;Capitalize the command line.
  94. NEXT_CAP:      LODSB
  95.                CMP    AL,CR
  96.                JZ     PARSE
  97.                CMP    AL,"/"
  98.                JNZ    CK_CAP
  99.                MOV    BYTE PTR [SI - 1],CR
  100.                LODSB
  101.                AND    AL,5FH
  102.                CMP    AL,"N"
  103.                JNZ    PARSE
  104.                MOV    MSG_FLAG,1
  105.                JMP    SHORT PARSE
  106. CK_CAP:        CMP    AL,"a"
  107.                JB     NEXT_CAP
  108.                CMP    AL,"z"
  109.                JA     NEXT_CAP
  110.                AND    BYTE PTR [SI - 1],5FH
  111.                JMP    NEXT_CAP
  112.  
  113. PARSE:         MOV    SI,81H                   ;Parse the command line.
  114. FIND_START:    LODSB                           ;Find first non-white space.
  115.                CMP    AL,CR
  116.                JNZ    CK_SPACE
  117.                MOV    DX,OFFSET FILE           ;If no parameter, display
  118.                JMP    ERROR_EXIT               ; error message.
  119. CK_SPACE:      CMP    AL,SPACE
  120.                JBE    FIND_START
  121.  
  122.                DEC    SI                       ;Adjust.
  123.                MOV    BP,SI                    ;BP = Filespec start.
  124.                MOV    FILESPEC_START,BP        ;Save it.
  125.                MOV    DX,SI                    ;DX = Filename start.
  126.                XOR    CX,CX                    ;CX = dot flag.
  127. FIND_END:      LODSB
  128.                CMP    AL,":"                   ;If colon or backslash found,
  129.                JZ     FOUND_PATH               ; it's a path specifier
  130.                CMP    AL,"\"
  131.                JNZ    CK_DOT
  132. FOUND_PATH:    MOV    DX,SI                    ;Filename start.
  133. CK_DOT:        CMP    AL,"."                   ;If dot, extension follows.
  134.                JNZ    CK_END
  135.                MOV    CX,SI
  136.                DEC    CX                       ;Adjust.
  137. CK_END:        CMP    AL,SPACE                 ;Carriage return marks end of
  138.                JA     FIND_END                 ; command line.
  139.                DEC    SI                       ;Adjust.
  140.                MOV    BYTE PTR [SI],0          ;ASCIIZ the filespec.
  141.                MOV    FILESPEC_END,SI          ;Save filespec end.
  142.                MOV    FILENAME_START,DX        ;Save filename start.
  143.                MOV    DOT_ADDRESS,CX           ;Save address of extension.
  144.  
  145.                MOV    DX,BP                    ;Retrieve filespec start.
  146.                MOV    AX,3D00H                 ;Open file for reading.
  147.                INT    21H
  148.                JNC    OPENED
  149.                MOV    BYTE PTR [SI],"$"        ;If failed, display message.
  150.                CALL   PRINT_STRING
  151.                MOV    DX,OFFSET NOT_FOUND
  152.                JMP    ERROR_EXIT
  153.  
  154. OPENED:        MOV    BX,AX                    ;Else, BX = filehandle.
  155.                MOV    DX,OFFSET BUFFER         ;Point to input buffer.
  156.                MOV    CX,(60 * 1024) + 1       ;Read 60K + 1.
  157.                MOV    AH,3FH
  158.                INT    21H
  159.                JNC    CK_SIZE
  160.                MOV    DX,OFFSET DISK_ERROR     ;If failed, disk error.
  161.                JMP    ERROR_EXIT
  162.  
  163. CK_SIZE:       CMP    AX,CX                    ;Did we read 60K + 1.
  164.                JNZ    SAVE_SIZE
  165.                MOV    DX,OFFSET TOO_BIG        ;If yes, too big.
  166.                JMP    ERROR_EXIT
  167.  
  168. SAVE_SIZE:     MOV    FILE_LENGTH,AX           ;Else, save file size.
  169.                MOV    AH,3EH                   ;Close input file.
  170.                INT    21H
  171.  
  172.                MOV    BX,FILESPEC_END          ;Retrieve filespec end.
  173.                MOV    BP,DOT_ADDRESS           ;Retrieve extension address.
  174.                OR     BP,BP                    ;Is there an extension?
  175.                JNZ    CK_EXE                   ;If yes, see if it's an EXE.
  176.                MOV    BP,BX                    ;Else, filename end=
  177.                                                ; filespec end.
  178.                JMP    SHORT STORE_NAME
  179.  
  180. CK_EXE:        MOV    SI,BP                    ;Point to extension address.
  181.                MOV    DI,OFFSET EXE            ;And ".EXE"
  182.                MOV    CX,4
  183.                REP    CMPSB
  184.                JNZ    STORE_NAME               ;If the extension is EXE then
  185.                MOV    EXE_FLAG,1               ; special case.
  186.                MOV    BX,BP                    ;filespec end=
  187.                                                ; extension address.
  188.  
  189. STORE_NAME:    MOV    SI,FILENAME_START        ;Filename.
  190.                MOV    CX,BX                    ;Calculate filename length.
  191.                SUB    CX,SI
  192.                MOV    FILENAME_LEN,CX          ;Save length
  193.                MOV    DI,OFFSET DTA + 3        ;Place name in DTA.
  194.                REP    MOVSB
  195.  
  196. MAKE_SCRIPT:   MOV    SI,OFFSET DOT_SCR        ;Convert filespec to script
  197.                MOV    DI,BP                    ; name by adding .SCR 
  198.                                                ; extension.
  199.                MOV    CX,6
  200.                REP    MOVSB
  201.  
  202.                MOV    DX,FILESPEC_START        ;Create a normal file with the
  203.                XOR    CX,CX                    ; .SCR extension on it's name.
  204.                MOV    AH,3CH
  205.                INT    21H
  206.                JNC    SAVE_HANDLE
  207.                MOV    DX,OFFSET DISK_ERROR     ;If failed, disk error.
  208.                JMP    ERROR_EXIT
  209. SAVE_HANDLE:   MOV    HANDLE,AX                ;Else, save file handle.
  210.  
  211.                MOV    CX,FILENAME_LEN          ;Retrieve length of filename.
  212.                ADD    CX,3                     ;Add 3 for space,"N",space.
  213.                CALL   WRITE                    ;Write to disk.
  214.  
  215. ;----------------------------------------------;
  216. ; This is the hexadecimal E loop.              ;
  217. ;----------------------------------------------;
  218.                MOV    BP,FILE_LENGTH           ;Retrieve file length.
  219.                MOV    SI,OFFSET BUFFER         ;Point to input file buffer.
  220. NEXT_LINE:     MOV    DI,OFFSET DTA + 1        ;Point to write storage.
  221.                MOV    CHAR_CT,3                ;Chars to write; start with 3.
  222.                CALL   E                        ;Get the (E)nter address.
  223.                MOV    CX,16                    ;16 numbers per line
  224.  
  225. NEXT_BYTE:     MOV    AL,SPACE                 ;Space delimiter.
  226.                STOSB
  227.                INC    CHAR_CT                  ;Count it.
  228.                LODSB                           ;Get a byte from input file.
  229.                CALL   CONVERT                  ;Convert to ASCII hexadecimal.
  230.                DEC    BP                       ;One less input character.
  231.                JZ     END_FILE                 ;If that last one, done.
  232.                LOOP   NEXT_BYTE                ;Else, do 16 numbers/line.
  233.                MOV    CX,CHAR_CT               ;Retrieve length of line.
  234.                CALL   WRITE                    ;Write it to disk.
  235.                JMP    SHORT NEXT_LINE          ;Next line.
  236.  
  237. END_FILE:      MOV    CX,CHAR_CT               ;Write the last line to disk.
  238.                CALL   WRITE
  239.  
  240.                MOV    DX,OFFSET RCX            ;Add "RCX" line.
  241.                MOV    CX,6
  242.                CALL   DOS_WRITE
  243.                MOV    AX,FILE_LENGTH           ;Retrieve length of file.
  244.                PUSH   AX                       ;Save low half.
  245.                MOV    AL,AH                    ;Convert high half to 
  246.                                                ; ASCII hex.
  247.                MOV    DI,OFFSET DTA + 1
  248.                CALL   CONVERT
  249.                POP    AX                       ;Retrieve low half and convert 
  250.                CALL   CONVERT                  ; it also to ASCII hex.
  251.                MOV    CX,5
  252.                CALL   WRITE                    ;Write that line to disk.
  253.                MOV    DX,OFFSET WQ             ;Write "W" and "Q".
  254.                MOV    CX,10
  255.                CALL   DOS_WRITE
  256.                CMP    MSG_FLAG,1
  257.                JZ     CLOSE_FILE
  258.                MOV    DX,OFFSET SCRIPT_END     ;Finish up with instuctions.
  259.                MOV    CX,SCRIPT_END_LEN
  260.                CALL   DOS_WRITE
  261.  
  262.                CMP    EXE_FLAG,1               ;Was there the special case of
  263.                JNZ    CLOSE_FILE               ; and EXE extension.
  264.                MOV    DX,OFFSET EXE_MSG        ;If no, done here.
  265.                MOV    CX,EXE_MSG_LENGTH        ;Else, add EXE message 
  266.                                                ; to script.
  267.                CALL   DOS_WRITE
  268.                MOV    DX,FILENAME_START        ;Add REN filename.
  269.                PUSH   DX
  270.                MOV    CX,FILENAME_LEN
  271.                PUSH   CX
  272.                CALL   DOS_WRITE
  273.                MOV    DX,OFFSET DTA            ;Add delimiting space.
  274.                MOV    CX,1
  275.                CALL   DOS_WRITE
  276.                POP    CX
  277.                POP    DX                       ;Add new name
  278.                CALL   DOS_WRITE
  279.                MOV    DX,OFFSET EXE            ; with the .EXE extension.
  280.                MOV    CX,6
  281.                CALL   DOS_WRITE
  282.  
  283. CLOSE_FILE:    MOV    BX,HANDLE                ;Close output file.
  284.                MOV    AH,3EH
  285.                INT    21H
  286.                JC     WRITE_FAIL
  287.                MOV    DX,FILESPEC_START        ;Retrieve output filespec.
  288.                CALL   PRINT_STRING             ;Display it followed by
  289.                MOV    DX,OFFSET CREATED        ; "created".
  290.                CALL   PRINT_STRING
  291.                XOR    AL,AL                    ;ErrorLevel = 0.
  292.                JMP    SHORT EXIT               ;Done.
  293.  
  294. ;----------------------------------------------;
  295. WRITE_FAIL:    MOV    DX,OFFSET DISK_ERROR     ;Generic disk error message.
  296. ERROR_EXIT:    CALL   PRINT_STRING
  297.                MOV    AL,1                     ;ErrorLevel = 1.
  298.  
  299. EXIT:          MOV    AH,4CH                   ;Terminate.
  300.                INT    21H
  301. MAIN           ENDP
  302.  
  303. ;********* SUBROUTINES *********;
  304.  
  305. DOS_WRITE:     MOV    AH,40H                   ;Write to file.
  306.                INT    21H
  307.                JC     WRITE_FAIL               ;Exit with message if failed.
  308.                RET
  309.  
  310. ;----------------------------------------------;
  311. ; INPUT: CX = count of chars to write.         ;
  312. ;----------------------------------------------;
  313. WRITE:         MOV    DX,OFFSET DTA            ;Point to Disk 
  314.                                                ; Transfer Area.
  315.                MOV    BX,HANDLE                ;Output filehandle.
  316.                CALL   DOS_WRITE                ;Write DTA.
  317. NEW_LINE:      MOV    BYTE PTR DTA + 1,CR      ;Add Carriage return 
  318.                                                ; and linefeed
  319.                MOV    BYTE PTR DTA + 2,LF
  320.                MOV    DX,OFFSET DTA + 1
  321.                MOV    CX,2
  322.                CALL   DOS_WRITE
  323.                RET
  324.  
  325. ;----------------------------------------------;
  326. E:             MOV    AL,"E"                   ;Store the "E"
  327.                STOSB
  328.                MOV    AL,SPACE                 ; and space delimiter.
  329.                STOSB
  330.                MOV    AX,LINE_NO               ;Retrieve the line number.
  331.                PUSH   AX
  332.                XCHG   AL,AH
  333.                CALL   CONVERT                  ;Convert high half to 
  334.                                                ; ASCII hex.
  335.                POP    AX
  336.                MOV    AX,LINE_NO
  337.                CALL   CONVERT                  ;Convert the low half.
  338.                ADD    LINE_NO,16               ;Next line number.
  339.                RET
  340.  
  341. ;----------------------------------------------------------;
  342. ; INPUT: AL = binary number; DI -> appropriate DTA address ;
  343. ;----------------------------------------------------------;
  344. CONVERT:       PUSH    CX                      ;Preserve loop counter.
  345.                MOV     DX,2                    ;Two ASCII 
  346.                                                ; hex bytes/binary byte.
  347.                MOV     BL,AL                   ;Preserve binary number.
  348. ROTATE:        MOV     CL,4
  349.                ROL     BL,CL                   ;Rotate by four bits.
  350.                MOV     AL,BL
  351.                AND     AL,0FH                  ;Mask off high four bits.
  352.                ADD     AL,"0"                  ;Convert to ASCII.
  353.                CMP     AL,"9"                  ;If A-F, add 7.
  354.                JBE     STORE_HEX
  355.                ADD     AL,7
  356. STORE_HEX:     STOSB                           ;Store in DTA.
  357.                INC     CHAR_CT                 ;Increment count to write.
  358.                DEC     DX                      ;Next half.
  359.                JNZ     ROTATE
  360.                POP     CX                      ;Restore loop counter.
  361.                RET
  362.  
  363. ;----------------------------------------------;
  364. PRINT_STRING:  MOV    AH,9                     ;DOS print string.
  365.                INT    21H
  366.                RET
  367.  
  368. DTA            DB      SPACE,"N",SPACE
  369. BUFFER         =       DTA + 100
  370.  
  371. _TEXT ENDS
  372. END   START
  373.